home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / cheetah.zip / CGETZP.C < prev    next >
C/C++ Source or Header  |  1992-08-21  |  9KB  |  262 lines

  1. /* cgetzp.c
  2.  *
  3.  * CHAINED mode version.
  4.  * NOTE that in this mode BPERROW is a permanent constant, and always equal to
  5.  * BPERROW_CHAINED.
  6.  *
  7.  * Description:
  8.  *      Get screen image and encode it to ZPacked format.
  9.  *      Uses the coding method, described in mputz4p.c
  10.  *
  11.  * Function list:
  12.  *      CgetZPacked().
  13.  *
  14.  * Portability: BORLANDC
  15.  *                                      (c) erdy 1992
  16.  * $Header: $
  17.  */
  18. #pragma inline
  19. #include <limits.h>
  20. #include <alloc.h>       /* farcoreleft() */
  21. #include "far.h"
  22. #include "vgaprefx.h"
  23. #include "vgadrv.h"
  24. #include "screen.h"
  25. #include "mxcpy.h"
  26.  
  27. /* Locals: */
  28. /*void near pascal stringstore(void);*/
  29.  
  30. #define checkempty() \
  31.     asm mov ax, di;\
  32.     asm dec ax;\
  33.     if (_AX == _BX) {\
  34.         /* Counter has been prepared, but hasn't been used.\
  35.          * So un-prepare it.\
  36.          */\
  37.         asm mov di, bx; /* Decrease pointer */\
  38.         asm dec dx;     /* Discount data byte */\
  39.     }
  40.  
  41. #define stringstore() {\
  42.     asm push ax;            /* Save ax */\
  43.     checkempty();\
  44.     asm xor al, al;\
  45.         asm stosb;              /* Store 0 */\
  46.         asm mov al, cl;         /* Put counter to al */\
  47.     asm stosb;              /* Store counter */\
  48.     asm pop ax;             /* Restore ax, ah must be kept */\
  49.         asm stosb;              /* Store color from al, now we can destroy al */\
  50.     /* Prepare new counter */\
  51.     asm mov bx, di;         /* New counter pointer */\
  52.     asm xor al, al;         /* Zero counter */\
  53.     asm stosb;              /* Store new counter */\
  54.         asm add dx, 4;          /* Count the data bytes */\
  55.         asm xor cx, cx;         /* Clear the counter */\
  56.         }
  57.  
  58. #define skipstore() {\
  59.     asm push ax;            /* Save ax */\
  60.     checkempty();\
  61.         asm mov al, cl;         /* Put counter to al */\
  62.     asm neg al;             /* Invert it */\
  63.     asm stosb;              /* Store counter */\
  64.     asm pop ax;             /* Restore ax, ah must be kept */\
  65.     /* Prepare new counter */\
  66.     asm mov bx, di;         /* New counter pointer */\
  67.     asm xor al, al;         /* Zero counter */\
  68.     asm stosb;              /* Store new counter */\
  69.         asm inc dx;\
  70.         asm inc dx;             /* Count the data bytes */\
  71.         asm xor cx, cx;         /* Clear the counter */\
  72.         }
  73.  
  74. #define checkfull(n) \
  75.     asm push ax;            /* Save ax */\
  76.     asm mov al, es:[bx];    /* Get counter value */\
  77.     if (_AL >= (SCHAR_MAX-n)) { /* Prepare new counter */\
  78.         asm mov bx, di;\
  79.         asm xor al, al;\
  80.         asm stosb;      /* Store 0 */\
  81.         asm inc dx;     /* Count data byte */\
  82.     }\
  83.         asm pop ax;
  84.  
  85.  
  86. Image far *CgetZPacked(unsigned int x, unsigned int y,
  87.                        unsigned int nc, unsigned int nr,
  88.                        int backcolor)
  89. {
  90.     char far *p;
  91.     Image far *ip;
  92.     auto unsigned int sz;
  93.     auto unsigned long coreleft;
  94.     auto int col;
  95.     auto int row;
  96.     auto union bw {
  97.         unsigned char b[2];
  98.         int  w;
  99.     } bc;
  100.  
  101.     bc.w = backcolor;
  102.  
  103.     if ((coreleft = (unsigned long)(nc + nc/2) * nr) > UINT_MAX)
  104.         sz = UINT_MAX;
  105.     else
  106.         sz = coreleft;
  107.         if ((coreleft = farcoreleft()/2) > UINT_MAX)
  108.                 coreleft = UINT_MAX;
  109.  
  110.         if (sz > coreleft)
  111.                 coreleft = sz;
  112.         coreleft -= 16;
  113. If_Overflow:
  114.     if ((p = getmem(sz)) == NULL) {
  115. Abort:
  116.         scerror = ER_OUTOFMEM;
  117.         return(NULL);
  118.     }
  119.     sz -= 16;
  120.  
  121.         _SI = VIDEO_ADDRESS(x, y);        /* Will keep video RAM offset */
  122.  
  123.     asm cld;
  124.     asm push ds;
  125.  
  126.     asm les di, p;                  /* Load data address */
  127.         _AX = Scdraw_seg;                /* Load video address */
  128.     _DS = _AX;
  129.     asm xor dx, dx;         /* Clear the used space counter */
  130.  
  131.         /* Registers on entrance:
  132.          * dx - counter of used space
  133.          * es - data segment, di - data offset
  134.          * ds - video ram segment, si - video ram offset
  135.          */
  136.         for (row = nr; --row >= 0;) {
  137.                 asm push si;            /* Save offset of 1st scanned pixel */
  138.                 asm xor cx, cx;         /* Set the color counter */
  139.  
  140.                 asm mov ax, nc;
  141.                 asm mov col, ax;
  142.  
  143.                 asm mov bx, di;         /* Save 1st counter pointer */
  144.                 asm xor al, al;
  145.                 asm stosb;              /* Prepare 1st counter */
  146.                 asm inc dx;             /* Count byte */
  147.                 asm lodsb;              /* Load first pixel */
  148.                 asm mov ah, al;         /* It will be old color */
  149.  
  150.                 goto EndLoop;
  151.                 /*for (col = ncols; --col >= 0;) {*/
  152. LineLoop:
  153.                         if (_DX >= sz) {        /* Out of space ? */
  154.                                 asm pop si;
  155.                                 asm pop ds;
  156.                                 retmem(p);
  157.                                 if (sz == coreleft)
  158.                                         goto Abort;
  159.                                 sz = coreleft+16;
  160.                                 goto If_Overflow;
  161.                         }
  162.  
  163.                         if (col != 0) {    /* Not a last pixel */
  164.                                 asm lodsb; /* Load color at ds:[si], advance si */
  165.                                 if (_AL == _AH) {  /* The same color ? */
  166.                                         asm inc cx; /* Count this pixel */
  167.                                         /* Not count the 1st pixel, because of flushing */
  168.                                         if (_CX >= SCHAR_MAX) {
  169.                                                 if ((bc.b[1]==0) && (bc.b[0]==_AL)) {
  170.                                                         skipstore();
  171.                                                 }
  172.                                                 else if (_CX >= UCHAR_MAX) {
  173.                                                         stringstore();
  174.                                                 }
  175.                                         }
  176.                                         goto EndLoop;
  177.                                 }
  178.                         }
  179.                         else if ((bc.b[1]==0) && (bc.b[0] == _AH)) {
  180.                                 /* Don't flush trailing transparent */
  181.                                 goto OutLoop;
  182.                         }
  183.                         /*
  184.                          * Store pixel literally.
  185.                          */
  186.                         asm xchg ah, al;
  187.                         /*
  188.                          * al now contains previous color,
  189.                          * ah contains new color.
  190.                          */
  191.                         if (_CX != 0) { /* Need to flush string */
  192.                                 asm inc cx;     /* Count 1st pixel */
  193.                                 if ((bc.b[1]==0) && (bc.b[0]==_AL)) {
  194.                                         skipstore();
  195.                                 }
  196.                                 else if (_CX > 3) {
  197.                                         stringstore();
  198.                                 }
  199.                                 else {
  200.                                         checkfull(3);
  201.                                         asm add es:[bx], cl; /* Increase counter */
  202.                                         asm add dx, cx;
  203.                                         asm rep stosb;
  204.                                 }
  205.                                 goto EndLoop;
  206.                         }
  207.                         if ( ((bc.b[1]==0) && (bc.b[0]==_AL)) ) {
  208.                                 /* Transparent color is always encoding
  209.                                         * in string form.
  210.                                         */
  211.                                 asm inc cx;
  212.                                 skipstore();
  213.                                 goto EndLoop;
  214.                         }
  215.                         checkfull(0);
  216.                         asm inc byte ptr es:[bx]; /* Increase counter */
  217.                         asm stosb;                /* Store value */
  218.                         asm inc dx;               /* Count data byte */
  219.                         /*goto EndLoop;*/
  220.                 /*}*/
  221. EndLoop:
  222.                 asm dec word pt